#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsRectItem>
#include <QTime>
#include <QKeyEvent>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setCentralWidget(ui->graphicsView);

    labelViewCord = new QLabel("View坐标：");
    labelViewCord->setMinimumWidth(150);
    labelSceneCord = new QLabel("Scene坐标");
    labelSceneCord->setMinimumWidth(150);
    labelItemCord = new QLabel("Item坐标");
    labelItemCord->setMinimumWidth(150);
    labelItemInfo = new QLabel("ItemInfo:");
    labelItemInfo->setMinimumWidth(150);

    ui->statusbar->addWidget(labelViewCord);
    ui->statusbar->addWidget(labelSceneCord);
    ui->statusbar->addWidget(labelItemCord);
    ui->statusbar->addWidget(labelItemInfo);

    ui->graphicsView->setCursor(Qt::ArrowCursor);
    ui->graphicsView->setMouseTracking(true); // 设置允许跟踪鼠标
    ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);

    initUI();

    connect(ui->graphicsView, SIGNAL(mouseMovePointSignal(QPoint)),
            this, SLOT(on_mouseMovePoint(QPoint)));

    connect(ui->graphicsView, SIGNAL(mousePressSignal(QPoint)),
            this, SLOT(on_mousePress(QPoint)));

    connect(ui->graphicsView, SIGNAL(keyPressSignal(QKeyEvent*)),
            this, SLOT(on_keyPress(QKeyEvent*)));

    connect(ui->graphicsView, SIGNAL(mouseDoubleClickSignal(QPoint)),
            this, SLOT(on_mouseDoubleClicked(QPoint)));

    // 随机item位置
    qsrand(QTime::currentTime().second());
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_keyPress(QKeyEvent *event)
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0) return;
    switch(event->key())
    {
    case Qt::Key_Delete:{
        for(int i = 0; i < cnt; i++)
        {
            QGraphicsItem *item = scene->selectedItems().at(0);
            scene->removeItem(item);
        }
        break;
    }
    case Qt::Key_Left:{
        for(int i = 0; i < cnt; i++)
        {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setX(item->pos().x()-1);
        }
        break;
    }
    case Qt::Key_Right:{
        for(int i = 0; i < cnt; i++)
        {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setX(item->pos().x()+1);
        }
        break;
    }
    case Qt::Key_Up:{
        for(int i = 0; i < cnt; i++)
        {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setY(item->pos().y()-1);
        }
        break;
    }
    case Qt::Key_Down:{
        for(int i = 0; i < cnt; i++)
        {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setY(item->pos().y()+1);
        }
        break;
    }
    default:
        break;
    }
}

void MainWindow::initUI()
{
   QRect rect(-300, -100, 600, 200);
   scene = new QGraphicsScene(rect);
   ui->graphicsView->setScene(scene);
   QGraphicsRectItem *item = new QGraphicsRectItem(rect);
   item->setFlags(QGraphicsItem::ItemIsFocusable
                  | QGraphicsItem::ItemIsSelectable
                  | QGraphicsItem::ItemIsMovable);

   ui->graphicsView->setRenderHint(QPainter::Antialiasing);
   ui->graphicsView->show();

}

void MainWindow::on_mouseMovePoint(QPoint point)
{
    labelViewCord->setText(QString::asprintf("View坐标：%d, %d",
                           point.x(), point.y()));

    QPointF pointScene = ui->graphicsView->mapToScene(point);
    labelSceneCord->setText(QString::asprintf("Scene坐标：%.0f, %.0f",
                           pointScene.x(), pointScene.y()));
}

void MainWindow::on_mousePress(QPoint point)
{
    //qDebug()<<"on_mouseClicked"<<endl;
    QPointF pointScene = ui->graphicsView->mapToScene(point);
    QGraphicsItem *item = nullptr;
    item = scene->itemAt(pointScene, ui->graphicsView->transform());
    if (item != nullptr)
    {
        QPointF pointItem = item->mapFromScene(pointScene);
        labelItemCord->setText(QString::asprintf("Item坐标：%.0f, %.0f",
                               pointItem.x(), pointItem.y()));
        labelItemInfo->setText("ID: " + item->data(ItemId).toString() + ", 描述: "
                               + item->data(ItemDescription).toString());

    }

}

#include <QColorDialog>
void MainWindow::on_mouseDoubleClicked(QPoint point)
{
    QGraphicsItem *item = nullptr;
    QPointF pointScene = ui->graphicsView->mapToScene(point);
    item = scene->itemAt(pointScene, ui->graphicsView->transform());
    if(item == nullptr) return;
    switch(item->type()){
    case QGraphicsRectItem::Type:
    {
        QGraphicsRectItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);// QGraphicsItem->QGraphicsRectItem
        QColor color = theItem->brush().color();
        QColor setColor = QColorDialog::getColor(color, this, "选择颜色");
        if(setColor.isValid())
            theItem->setBrush(QBrush(setColor));
        break;
    }
    case QGraphicsEllipseItem::Type:
    {
        QGraphicsEllipseItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
        QColor color = theItem->brush().color();
        QColor setColor = QColorDialog::getColor(color, this, "选择颜色");
        if(setColor.isValid())
            theItem->setBrush(QBrush(setColor));
        break;
    }
    case QGraphicsPolygonItem::Type:
    {
        QGraphicsPolygonItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
        QColor color = theItem->brush().color();
        QColor setColor = QColorDialog::getColor(color, this, "选择颜色");
        if(setColor.isValid())
            theItem->setBrush(QBrush(setColor));
        break;
    }
    case QGraphicsLineItem::Type:
    {
        QGraphicsLineItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
        QColor color = theItem->pen().color();
        QColor setColor = QColorDialog::getColor(color, this, "选择颜色");
        if(setColor.isValid())
            theItem->setPen(QPen(setColor));
        break;
    }
    case QGraphicsTextItem::Type:
    {
        QGraphicsTextItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
        QColor color = theItem->defaultTextColor();
        QColor setColor = QColorDialog::getColor(color, this, "选择颜色");
        if(setColor.isValid())
            theItem->setDefaultTextColor(setColor);
        break;
    }
    default:
        break;
    }

}

// 创建矩形item
void MainWindow::on_actionRect_triggered()
{
   auto *item = new QGraphicsRectItem(-50, -30, 100, 60);
   item->setFlags(QGraphicsItem::ItemIsMovable
                  | QGraphicsItem::ItemIsSelectable
                  | QGraphicsItem::ItemIsFocusable);

   scene->addItem(item);
   scene->clearSelection();
   item->setSelected(true);
   item->setBrush(QBrush(Qt::yellow));
   item->setPos(-100+qrand()%200, -60+qrand()%120);
   item->setData(ItemId, seqNum++); // item的数据，相当于一张卡片
   item->setData(ItemDescription, "矩形");
}

void MainWindow::on_actionCircle_triggered()
{
    auto *item = new QGraphicsEllipseItem(-50, -50, 100, 100);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   | QGraphicsItem::ItemIsSelectable
                   | QGraphicsItem::ItemIsFocusable);

    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
    item->setBrush(QBrush(Qt::blue));
    item->setPos(-100+qrand()%200, -60+qrand()%120);
    item->setData(ItemId, seqNum++); // item的数据，相当于一张卡片
    item->setData(ItemDescription, "圆形");
}

void MainWindow::on_actionEllip_triggered()
{
    auto *item = new QGraphicsEllipseItem(-50, -50, 100, 60);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   | QGraphicsItem::ItemIsSelectable
                   | QGraphicsItem::ItemIsFocusable);

    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
    item->setBrush(QBrush(Qt::green));
    item->setPos(-100+qrand()%200, -60+qrand()%120);
    item->setData(ItemId, seqNum++); // item的数据，相当于一张卡片
    item->setData(ItemDescription, "椭圆");
}

void MainWindow::on_actionLine_triggered()
{
    auto *item = new QGraphicsLineItem(-100, 0, 100, 0);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   | QGraphicsItem::ItemIsSelectable
                   | QGraphicsItem::ItemIsFocusable);

    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
    QPen pen;
    pen.setColor(Qt::black);
    pen.setWidth(3);
    item->setPen(pen);
    item->setPos(-100+qrand()%200, -60+qrand()%120);
    item->setData(ItemId, seqNum++); // item的数据，相当于一张卡片
    item->setData(ItemDescription, "直线");
}

void MainWindow::on_actionPolygon_triggered()
{
    auto *item = new QGraphicsPolygonItem();
    QPolygonF points;
    points.append(QPointF(-30, -40));
    points.append(QPointF(30, -40));
    points.append(QPointF(60, 0));
    points.append(QPointF(-60, 0));

    item->setPolygon(points);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   | QGraphicsItem::ItemIsSelectable
                   | QGraphicsItem::ItemIsFocusable);

    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
    item->setBrush(QBrush(Qt::cyan));
    item->setPos(-100+qrand()%200, -60+qrand()%120);
    item->setData(ItemId, seqNum++); // item的数据，相当于一张卡片
    item->setData(ItemDescription, "梯形");
}

void MainWindow::on_actionTriangle_triggered()
{
    auto *item = new QGraphicsPolygonItem();
    QPolygonF points;
    points.append(QPointF(0, -40));
    points.append(QPointF(60, 40));
    points.append(QPointF(-60, 40));

    item->setPolygon(points);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   | QGraphicsItem::ItemIsSelectable
                   | QGraphicsItem::ItemIsFocusable);

    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
    item->setBrush(QBrush(Qt::magenta));
    item->setPos(-100+qrand()%200, -60+qrand()%120);
    item->setData(ItemId, seqNum++); // item的数据，相当于一张卡片
    item->setData(ItemDescription, "三角形");
}

#include <QInputDialog>
void MainWindow::on_actionText_triggered()
{
    QString str = QInputDialog::getText(this, "输入", "请输入文字：");
    auto *item = new QGraphicsTextItem(str);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   | QGraphicsItem::ItemIsSelectable
                   | QGraphicsItem::ItemIsFocusable);

    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
    QFont font;
    font.setPointSize(18);
    item->setFont(font);
    item->setDefaultTextColor(Qt::black);
    item->setPos(-100+qrand()%200, -60+qrand()%120);
    item->setData(ItemId, seqNum++); // item的数据，相当于一张卡片
    item->setData(ItemDescription, "文字");
}

void MainWindow::on_actionZoomIn_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        ui->graphicsView->scale(1.1, 1.1);
        return;
    }
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(i);
        item->setScale(0.1 + item->scale());
    }
}

void MainWindow::on_actionZoomOut_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        ui->graphicsView->scale(0.9, 0.9);
        return;
    }
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(i);
        item->setScale(item->scale() - 0.1);
    }
}

void MainWindow::on_actionRestore_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        ui->graphicsView->resetTransform();
        return;
    }
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(i);
        item->setScale(1);
    }
}

void MainWindow::on_actionRotateLeft_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        ui->graphicsView->rotate(-45);
        return;
    }
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(i);
        item->setRotation(item->rotation()-45);
    }
}

void MainWindow::on_actionRotateRight_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        ui->graphicsView->rotate(45);
        return;
    }
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(i);
        item->setRotation(item->rotation()+45);
    }
}

void MainWindow::on_actionEdit_Front_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        return;
    }
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(i);
        item->setZValue(item->zValue()+1);
    }
}

void MainWindow::on_actionEdit_back_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        return;
    }
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(i);
        item->setZValue(item->zValue()-1);
    }
}

void MainWindow::on_actionGroup_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt <= 1)
    {
        return;
    }
    QGraphicsItemGroup *group = new QGraphicsItemGroup;
    scene->addItem(group);
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(0);
        item->setSelected(false); // 每次取走一个item，迭代器会失效
        group->addToGroup(item);
    }
    group->setFlags(QGraphicsItem::ItemIsMovable
                    | QGraphicsItem::ItemIsFocusable
                    | QGraphicsItem::ItemIsSelectable);
    group->setSelected(true);
}

void MainWindow::on_actionGroupBreakk_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        return;
    }
    QGraphicsItemGroup *group = new QGraphicsItemGroup;
    scene->addItem(group);
    QList<QGraphicsItemGroup*> list;
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(i);
        if(item->type() == QGraphicsItemGroup::Type)
        {
            QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup*>(item);
            list.append(group); // 先保存下来，不要在for循环内部做打散操作
        }
    }
    foreach(auto gItem, list)
    {
        scene->destroyItemGroup(gItem);
    }
}

void MainWindow::on_actionDelete_triggered()
{
    int cnt = scene->selectedItems().count();
    if(cnt == 0)
    {
        return;
    }
    for(int i = 0; i < cnt; i++)
    {
        auto item = scene->selectedItems().at(0);
        scene->removeItem(item);
    }
}
